package com.zyj.core.handler.statementhandler;

import com.zyj.core.config.Configuration;
import com.zyj.core.config.MappedStatement;
import com.zyj.core.sqlsource.BoundSql;

import java.sql.Connection;
import java.sql.Statement;
import java.util.List;

/**
 * 当前类RoutingStatementHandler仅仅只用来做路由，没有别的作用
 */
public class RoutingStatementHandler implements StatementHandler {
    private StatementHandler delegate;

    /**
     * 委托设计模式
     * <p>
     * 由RoutingStatementHandler根据statementType选择一个对应的真正的StatementHandler来执行查询
     *
     * @param statementType
     * @param configuration
     */
    public RoutingStatementHandler(String statementType, Configuration configuration) {
        switch (statementType) {
            case "prepared":
                delegate = new PreparedStatementHandler(configuration);
                break;
            case "callable":
                delegate = new CallableStatementHandler(configuration);
                break;
            case "simple":
                delegate = new SimpleStatementHandler(configuration);
            default:
                // 默认是PreparedStatementHandler
                delegate = new PreparedStatementHandler(configuration);
        }

    }

    /**
     * 调用真正的StatementHandler来执行得到对应类型的Statement对象
     *
     * @param connection
     * @param sql
     * @return
     * @throws Exception
     */
    @Override
    public Statement prepare(Connection connection, String sql) throws Exception {
        return delegate.prepare(connection, sql);
    }

    /**
     * 调用真正的StatementHandler来完成参数解析，来给sql设置参数
     *
     * @param statement
     * @param param
     * @param boundSql
     * @throws Exception
     */
    @Override
    public void parameterize(Statement statement, Object param, BoundSql boundSql) throws Exception {
        delegate.parameterize(statement, param, boundSql);
    }

    /**
     * 调用真正的StatementHandler来执行查询
     *
     * @param statement
     * @param mappedStatement
     * @param <T>
     * @return
     * @throws Exception
     */
    @Override
    public <T> List<T> query(Statement statement, MappedStatement mappedStatement) throws Exception {
        return delegate.query(statement, mappedStatement);
    }
}
